#!/bin/bash

# apt-cyg: install tool for cygwin similar to debian apt-get
# 
# Copyright (C) 2005-9, Stephen Jungels
# Enhanced version copyright (C) 2010, atomicdryad -a-t- gmail
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# (http://www.fsf.org/licensing/licenses/gpl.html)

# this script requires some packages
###################################################################
##### Configurable variables
declare -a repos_name=( 'cygwin' 'ports' )                       ## repository names
declare -a repos_url=( "http://mirror.mcs.anl.gov/cygwin/"       ## repository urls
  "http://mirrors.kernel.org/sources.redhat.com/cygwinports/" )  #    must match names
declare -a repos_checked=( '0' '0' )                             ## add an additional '0' for each repo
###########################################################

OLDIFS=$IFS
RELEASE="release"
#-2"
SETUP="setup"
#-2"
WGET=`which wget 2> /dev/null`
BZIP2=`which bzip2 2> /dev/null`
TAR=`which tar 2> /dev/null`
GAWK=`which awk 2> /dev/null`




if ! COL=$(stty -a|head -1|egrep -o 'columns [^;]*'|cut -d ' ' -f2 2> /dev/null); then
  unset COL
fi
#echo $COL
if test "-$WGET-" = "--" || test "-$BZIP2-" = "--" || test "-$TAR-" = "--" \
  || test "-$GAWK-" = "--"
then
  echo You must install wget, tar, gawk and bzip2 to use apt-cyg.
  exit 1
fi

PAD="                                                                                                                                                                                                        "
function usage()
{
  echo apt-cyg: Installs and removes Cygwin packages.
  echo "  \"apt-cyg install <package names>\" to install packages"
  echo "  \"apt-cyg remove <package names>\" to remove packages"
  echo "  \"apt-cyg update\" to update $SETUP.ini"
  echo "  \"apt-cyg show\" to show installed packages"
  echo "  \"apt-cyg find <patterns>\" to find packages matching patterns"
  echo "  \"apt-cyg describe <patterns>\" to describe packages matching patterns"
  echo "  \"apt-cyg packageof <commands or files>\" to locate parent packages"
  echo "Options:"
  echo "  --mirror, -m <url> : set mirror"
  echo "  --cache, -c <dir>  : set cache"
  echo "  --file, -f <file>  : read package names from file"
  echo "  --noupdate, -u     : don't update $SETUP.ini from mirror"
  echo "  --all, -a          : search descriptions too"
  echo "  --help"
  echo "  --version"
}



function version()
{
  echo "apt-cyg version ENH 0.57-0.1"
  echo "Written by Stephen Jungels"
  echo "Enhanced by atomicdryad (gmail)"
  echo "Copyright (c) 2005-9 Stephen Jungels & atomicdryad.  Released under the GPL."
}

function die() {
  echo "$1"
  exit 1
}

function get-setuprc() {
  local line=$(( $(cat /etc/setup/setup.rc | grep -n "^$1"|cut -d : -f1) + 1))
  if [ $line -le 1 ]; then
    die "/etc/setup/setup.rc: Cannot find '$1' variable."; fi
  local ret=$(head -$line /etc/setup/setup.rc|tail -1|tr -d '[:space:]')
  if [ "x$ret" == "x" ]; then
    die "/etc/setup/setup.rc: '$1' not set."; fi
  if [ "x$2" != "x" ]; then
    if ( ! [[ $ret =~ $2 ]]); then
      die "/etc/setup/setup.rc: Invalid data for '$1': $ret"; fi; fi
  echo $ret
}

function set-setuprc-revert() {
  echo "$1"
  exit 1
}

function set-setuprc() {
  if [ "x$2" == "x" ]; then
    die "/etc/setup/setup.rc: No argument for setting '$1'"; fi
  local line=$(( $(cat /etc/setup/setup.rc | grep -n "^$1"|cut -d : -f1) + 1))
  if [ $line -le 1 ]; then
    die "/etc/setup/setup.rc: Cannot find '$1' variable. Run setup.exe before this."; fi
  local ret=$(head -$line /etc/setup/setup.rc|tail -1|tr -d '[:space:]')
  if [ "x$ret" == "x" ]; then
    die "/etc/setup/setup.rc: '$1' not set. Run setup.exe before this."; fi
  #echo "/etc/setup/setup.rc: Replacing line $line: '$ret'";
  local r2=$(echo "$ret"|sed 's,\\,\\\\,g')
  local s2=$(echo "$2"|sed 's,\\,\\\\,g')
  sed "${line}s,$r2,$s2," < /etc/setup/setup.rc > /tmp/setup.rc.tmp.$$
  local line=$(( $(cat /tmp/setup.rc.tmp.$$ | grep -n "^$1"|cut -d : -f1) + 1))
  if [ $line -le 1 ]; then
    die "/etc/setup/setup.rc: Cannot find '$1' variable after editing."; fi
  local ret=$(head -$line /tmp/setup.rc.tmp.$$|tail -1|tr -d '[:space:]')
  if [ "x$ret" != "x$2" ]; then
    die "/etc/setup/setup.rc: '$1' variable set to '$ret', not '$2'."; fi
  cat /tmp/setup.rc.tmp.$$ > /etc/setup/setup.rc
  rm /tmp/setup.rc.tmp.$$
}

function findworkspace()
{

  mirror=${repos_url[0]}
  #ftp://ftp.gtlib.gatech.edu/pub/cygwin/
  cache=/setup
  mirror=$(get-setuprc "last-mirror" '^(ftp|https?)://......*/.*')
  cache=$(get-setuprc "last-cache" '^[a-zA-Z]:\\...*')
  mirrordir="`echo "$mirror" | sed -e "s/:/%3a/g" -e "s:/:%2f:g"`"
  
  echo Working directory is $cache

  for (( c = 0 ; c < ${#repos_url[@]} ; c++ )); do
    if [ "x$mirror" == "x${repos_url[$c]}" ]; then
      mirroridx=$c
      break
    fi
  done
  echo "Mirror is $mirror ($mirroridx)"

  if [ ! -e "$cache/$mirrordir" ]; then mkdir -p "$cache/$mirrordir"; fi
  cd "$cache/$mirrordir"
}


function getsetup() 
{
  if test "$noscripts" == "0" -a "$noupdate" == "0"
  then
    #touch $SETUP.ini
    mv -f $SETUP.ini $SETUP.ini-save
    #rm -f $SETUP.bz2
    wget -c $mirror/$SETUP.bz2
    if test -e $SETUP.bz2 && test $? -eq 0
    then
      bunzip2 $SETUP.bz2
      if [ $? -eq 0 ]; then
        mv $SETUP $SETUP.ini
        echo Updated $SETUP.ini
      fi
    else
      wget $mirror/$SETUP.ini
      if test -e $SETUP.ini && test $? -eq 0
      then
        echo Updated $SETUP.ini
      else
        mv $SETUP.ini-save $SETUP.ini
        echo Error updating $SETUP.ini, reverting
      fi
    fi
  fi
  INI=$(readlink -f "$SETUP.ini")
}

function cmdfind() {
    search="$1"
    repo="$2"
    desc="$3"
    IFS="
"
    for pkg in $(cat $SETUP.ini |grep -Ev '^(#|setup-.*: )'| 
      tr -c '[:print:][:cntrl:]' '[?*]' |
      awk -v query="$search" -v descsearch="$desc" '
        BEGIN{
          RS="\n\n\100 "; FS="\n"; ORS=""
        } {
          if ( $2 ~ /^sdesc: / ) {
            if ( ($1 ~ query) || ( ( descsearch == 1 ) && ( $2 ~ query ) ) ) {
              print $1
              print gensub(/.*[\r\n]sdesc: "([^"\r\n]*).*/,"{desc=\\1",1)
              sub(/[\r\n]\[prev\][\r\n].*/,"")
              if (/category: _obsolete/) {
                print "{OBSOLETE"
              }
              if (/source: /) {
                if (! /install: /) {
                  print "{SRC-ONLY"
                }
              }
              if (/version: /) {
                print gensub(/.*\nversion: ([^\r\n]*).*/,"{version=\\1",1)
              }
              print "\n"
            }
          }
        }
        '); do
        extra=""
        desc=""
        name=""
        version=""
        skip=""
        OLDIFS="$IFS"



        IFS="{"
        set -- $pkg
        name=$1
        shift 
        unset pkga
        declare -a pkga=($@)
        IFS="="
        for (( i = 0 ; i < ${#pkga[@]} ; i++ )); do
          set -- ${pkga[$i]}
          #printf "arg(${#arg})($i/${#pkga[@]}): ${pkga[$i]}: '$1', '$2'\n"          
          case "$1" in
            desc) desc="$2";;
            version) version="$2";;
            OBSOLETE) skip="1";;
            *) extra="${extra}${1:0:1}";;
          esac
        done

        IFS=" 	
"
       if [ "x$skip" != "x1" ]; then
        key=${name//-/DASHKLUDGE}          
        key=${key//./DOTKLUDGE}
        key=${key//+/PLUSKLUDGE}
        var="INSTALLED_$key"
        iversion=""
        iversion=${!var}

        if [ "x$extra" != "x" ]; then
          name="$name [$extra]";
        fi
        if [ "x$version" != "x" ]; then
          desc="$version - $desc"
        fi
       if [ "x$FIND" == "xnew" ]; then
         if [ "x$iversion" == "x" ]; then continue; fi
         if [ "x$iversion" == "x$version" ]; then continue; fi 
       fi
        str="${name}$PAD"

        #if [ "x$repo" != "x" ]; then
          str="${str:0:30}${repo}$PAD" 
        #fi
        str="${str:0:42}"${iversion}"$PAD"
        echo "${str:0:54}$desc"
        
       fi
      done
  IFS=" 
"
}
function checkpackages()
{
  if test "-$packages-" = "--"
  then
    echo Nothing to do, exiting
    exit 0
  fi
}
function _splitbase() {
  base=$1
}
function getinstalled() {
    tab=$(echo -ne '\t')
    IFS="
"
    for line in $(cat /etc/setup/installed.db|awk '/^([^ ]+) ([^ ]+) 0$/ {n=$1;v=substr($2,length($1)+2);v=substr(v,1,length(v)-length(".tar.bz2"));printf "%s\t%s\n",n,v}'); do 
      #printf "lol1:$line:lol2\n"
      IFS=$tab
      _splitbase $line;
      #echo "base1:$base:base2:"
      if [ ! -e "/etc/setup/$base.lst.gz" ]; then
        echo NOT installed correctly: $base
      else
      declare -a arr=($line)
      key=${arr[0]//-/DASHKLUDGE}
      key=${key//./DOTKLUDGE}
      key=${key//+/PLUSKLUDGE}
      export INSTALLED_"$key"="${arr[1]}"
      fi
    done
    IFS=$OLDIFS
}


function chkpkgini() {
  chkpkgini=0
  local pkg="$1"
  local ini="$2"
  desc=$(cat "$ini" | awk -v package="$pkg" \
    'BEGIN{RS="\n\n@ "; FS="\n"} {if ($1 == package) {desc = $0; px++}} \
     END {if (px == 1 && desc != "") print desc; else print "Package not found"}')
  echo "$desc"
  if [ "-$desc-" = "-Package not found-" ] || ( $(echo "$desc"|grep -q '^category: _obsolete') && [ "x$ALLOWOBSOLETE" == "x" ] ); then
    if [ "-$desc-" = "-Package not found-" ]; then
      return 1
    else
      return 2
    fi
    return
  else
    return 0
  fi
}
declare -a chkpkginierrstr=('PKG found' 'PKG not found' 'Obsolete package')

function findpkgall() {
  local pkg="$1"
  local idx="$2"
#  set -x
  for (( c = 0 ; c < ${#repos_url[@]} ; c++ )); do
    if [ "x$c" == "x$idx" ]; then
      #echo -n "  [mirror:$c] ${repos_url[$c]}: skipping..."
      continue                                 
    fi
    dir="`echo "${repos_url[$c]}" | sed -e "s/:/%3a/g" -e "s:/:%2f:g"`"
    if desc=$(chkpkgini "$pkg" "$cache/$dir/$SETUP.ini"); then 
      echo -n "  [mirror:$c] ${repos_url[$c]}: Found it..."
      findpkg[0]="${repos_url[$c]}"
      findpkg[1]="$desc"
      return
    else
      rc=$?
      echo -n "  [mirror:$c] ${repos_url[$c]}: ${chkpkginierrstr[$rc]}..."
    fi
  done
}


function getdeps() {
  local spaces="                                                          "
  local depth=$(( $2 + 1 ))
  local d2=$(( $depth * 2 ))
  echo -n "${spaces:1:$d2}\`- $1: "
  local pkg="$1"
  local todo=""

  local mirror="$mirror"

  #mkdir -p "$RELEASE/$pkg"

  if ! desc=$(chkpkgini "$pkg" "$INI"); then
    #rc=$?
    #if [ "-$desc-" = "-Package not found-" ]; then
    #  echo "Package $pkg not found or ambiguous name ($SETUP, $RELEASE, $cache/$mirrordir)"
    #else
    #  echo "Package $pkg is marked as obsolete, dropping. (Run with -o to override)"
    #fi

    declare -a findpkg=('' '');
    findpkgall "$pkg" "$mirroridx"
    if [ "x${findpkg[0]}" == "x" ]; then
      bad="$bad $pkg"
      packages=$(echo "$packages"|tr ' ' '\n'|egrep -vw "$pkg"|tr '\n' ' '|sed -r 's,(^ +| +$),,g')
      return
    else
      
      mirror="${findpkg[0]}"
      desc="${findpkg[1]}"
    fi
  fi
pkglist="$pkg $pkglist"
pkgmlist="$mirror $pkgmlist"

  requires=$(echo "$desc" |awk '/^requires: / {s=gensub("(requires: )?([^ ]+) ?", "\\2 ", "g", $0); print s}')

#echo "req:$requires";exit
  for req in $requires; do
    if $(echo "$packages"|tr ' ' '\n'|grep -qw "$req"); then
    #grep -qE "^$req\$"); then
      #echo -n "$req(todo)..."
      continue
    fi
    if $(echo "$INSTALLED"|grep -q "^$req\$" ); then
      if [ ! -e "/etc/setup/$req.lst.gz" ]; then
        echo -n "$req(broken install)..."
      else
        #echo -n "$req(installed)..."
        continue
      fi
    fi
    echo -n "$req..."
    packages="$req $packages"
    todo="$req $todo"
  done
  echo
  for req in $todo; do
    getdeps $req $depth
  done
}


function dlpkg() {
  pkg="$1"
  binsrc="$2"
  local mirror="$mirror"
  desc=$(cat "$INI" | awk -v package="$pkg" \
    'BEGIN{RS="\n\n@ "; FS="\n"} {if ($1 == package) {desc = $0; px++}} \
     END {if (px == 1 && desc != "") print desc; else print "Package not found"}')
    
  if test "-$desc-" != "-Package not found-"; then
    found=1
  else
    found=0
    echo "  ${dryrun}$pkg: Package not found or ambiguous name, exiting. ($cache/$mirrordir)"
    if [ "x$mirroridx" != "x" ]; then
      repos_checked[$mirroridx]=1
    fi
      for (( c = 0 ; c < ${#repos_url[@]} ; c++ )); do
        if [ "x$c" == "x$mirroridx" ]; then
          echo "  [$c] ${repos_url[$c]}: skipping."
          continue
        fi
        dir="`echo "${repos_url[$c]}" | sed -e "s/:/%3a/g" -e "s:/:%2f:g"`"
        #echo "Trying ${repos_url[$c]} $cache/$dir/$SETUP.ini"
        desc=$(cat "$cache/$dir/$SETUP.ini" | awk -v package="$pkg" \
          'BEGIN{RS="\n\n@ "; FS="\n"} {if ($1 == package) {desc = $0; px++}} \
          END {if (px == 1 && desc != "") print desc; else print "Package not found"}')
        if test "-$desc-" != "-Package not found-"; then
          echo "  [$c] ${repos_url[$c]}: Found it."
          found=1
          mirror="${repos_url[$c]}"
          break
        else 
          echo "  [$c] ${repos_url[$c]}: Not found."
        fi
      done
    #fi
  fi
  if [ "x$found" != "x1" ]; then  
    exit 1
  fi
  echo "  ${dryrun}$pkg: Found package."
    
    # download and unpack the bz2 file
  IFS="
"
    # pick the latest version, which comes first
  IFS="$oldifs"
  if [ "x$binsrc" == "xsrc" ]; then
    install=`echo "$desc" | awk '/source: / { print $2; exit }'` 
    digest=`echo "$desc" | awk '/source: / { print $4; exit }'` 
  else
    install=`echo "$desc" | awk '/install: / { print $2; exit }'` 
    digest=`echo "$desc" | awk '/install: / { print $4; exit }'` 
  fi
    file=`basename $install`
    #echo "pwd=`pwd`, mirror=$mirror, install='$install', digest='$digest', file='$file'";return

    if [ -e "$file" ]; then
      digold=`md5sum $file | awk '{print $1}'`
      if [ "x$digest" != "x$digold" ]; then
        echo "  $pkg: old package, MD5 sum did not match.";
        rm -f "$file"
        wget -nc $mirror/$install

      fi
    else
      wget -nc $mirror/$install
    fi
    # check the md5

    digactual=`md5sum $file | awk '{print $1}'`

    #if ! test $digest = $digactual; then
    if [ "x$digest" != "x$digactual" ]; then
      die "  $pkg: $digactual did not match $digest, exiting";
    fi
}

function installpkg() {
  local pkg="$1"
  local mirror="$2"
    already=`grep -c "^$pkg " /etc/setup/installed.db`
    if test $already -ge 1
    then
      if [ ! -e "/etc/setup/$pkg.lst.gz" ]; then
        echo "${dryrun}$pkg: installed but has no /etc/setup/$pkg.lst.gz, installing..."
      else
        #echo "${dryrun}$pkg: already installed, skipping."
        #return
        echo "${dryrun}$pkg: already installed."
      fi
    else
      echo "${dryrun}$pkg: Installing..."
    fi

  local dir="`echo "$mirror" | sed -e "s/:/%3a/g" -e "s:/:%2f:g"`"
  mkdir -p "$cache/$dir/$RELEASE/$pkg"

  if desc=$(chkpkgini "$pkg" "$cache/$dir/$SETUP.ini"); then
    echo "  ${dryrun}$pkg: Found package."
  else
    rc=$?
    echo "  ${dryrun}$pkg: Error - ${chkpkginierrstr[$rc]}"
    exit 1
  fi
  if [ "x$dryrun" != "x" ]; then
    echo "  ${dryrun}Exiting due to --dry-run."
    return
  fi
  mkdir -p "$cache/$dir/$RELEASE/$pkg"
  echo "$desc" > "$cache/$dir/$RELEASE/$pkg/desc"
  cd "$cache/$dir/$RELEASE/$pkg"
  install=$(echo "$desc"| awk '/install: / { print $2; exit }')
  digest=`cat "desc" | awk '/install: / { print $4; exit }'` 
  file=$(basename "$install")
  if [ -e "$file" ]; then
    digold=`md5sum $file | awk '{print $1}'`
    if [ "x$digest" != "x$digold" ]; then
      echo "  $pkg: old package, MD5 sum did not match ($digest/$digold)."
      ls -ld "$file";
      rm -f "$file"
      wget -nc $mirror/$install
    fi
  else
    wget -nc $mirror/$install
  fi
    # check the md5
  digactual=`md5sum $file | awk '{print $1}'`
  if [ "x$digest" != "x$digactual" ]; then
    die "  $pkg: $file - $digactual did not match $digest, exiting"; fi

  file2=$(basename "$file" .bz2)
  echo -n "  $pkg: Uncompressing..."
  
  
    file2=$(basename "$file" .bz2)
    echo -n "  $pkg: Uncompressing..."
    bunzip2 -c $file > /tmp/$file2
    rc=$?
    if [ $rc -gt 0 ]; then
      die "  $pkg:  bunzip2 -c $file failed with return code $rc, exiting.";  fi
    if [ "$command" == "fakeinstall" ]; then
      cat /tmp/$file2 | tar tf - > "/etc/setup/$pkg.lst"
    else    
      echo -n "Unpacking..."
      cat /tmp/$file2 | tar > "/etc/setup/$pkg.lst" xvf - -C /
    fi
    echo "done."
    rm -f /tmp/$file2
    gzip -f "/etc/setup/$pkg.lst"
    cd ../..
    
    # update the package database
    
    cat /etc/setup/installed.db | awk > /tmp/awk.$$ -v pkg="$pkg" -v bz=$file \
      '{if (ins != 1 && pkg < $1) {print pkg " " bz " 0"; ins=1}; print $0} \
       END{if (ins != 1) print pkg " " bz " 0"}'
    mv /etc/setup/installed.db /etc/setup/installed.db-save
    mv /tmp/awk.$$ /etc/setup/installed.db
    
    if [ "$command" == "fakeinstall" ]; then
      echo "  $pkg: Fake installed.";
    else
      pis=`ls /etc/postinstall/*.sh 2>/dev/null | wc -l`
      if test $pis -gt 0 && ! test $noscripts -eq 1;then
        echo -n "  $pkg: Running postinstall scripts..."
        for script in /etc/postinstall/*.sh; do
          echo -n "$script..."
          $script
          ret=$?
          mv $script $script.done
          if [ "x$ret" != "x0" ]; then
            echo -e "\n    Script $script exited with error code $ret. Hit any key to continue or ^C to exit."
            read -sn 1 scrap
          fi
        done
        echo
      fi    
    fi
    echo " "
  

}

function oldinstallpkg() {
  pkg="$1"
  local mirror="$2"

    # look for package and save desc file

    mkdir -p "$RELEASE/$pkg"
    cat $SETUP.ini | awk > "$RELEASE/$pkg/desc" -v package="$pkg" \
      'BEGIN{RS="\n\n@ "; FS="\n"} {if ($1 == package) {desc = $0; px++}} \
       END {if (px == 1 && desc != "") print desc; else print "Package not found"}' 
    
    desc=`cat "$RELEASE/$pkg/desc"`
    if test "-$desc-" = "-Package not found-"
    then
      echo "  ${dryrun}$pkg: Package not found or ambiguous name, exiting. ($cache/$mirrordir)"
      rm -r "$RELEASE/$pkg"
      exit 1
    fi
    echo "  ${dryrun}$pkg: Found package."
    
    if [ "x$dryrun" != "x" ]; then
      echo "  ${dryrun}Exiting due to --dry-run."
      rm -r "$RELEASE/$pkg"
      return
    fi
    
    # download and unpack the bz2 file
    
    # pick the latest version, which comes first
    install=`cat "$RELEASE/$pkg/desc" | awk '/install: / { print $2; exit }'` 
    file=`basename $install`
    cd "$RELEASE/$pkg"
    
               
    if [ -e "$file" ]; then
      digold=`md5sum $file | awk '{print $1}'`
      if [ "x$digest" != "x$digold" ]; then
        echo "  $pkg: old package, MD5 sum did not match.";
        rm -f "$file"
        wget -nc $mirror/$install

      fi
    else
      wget -nc $mirror/$install
    fi
    # check the md5
    digest=`cat "desc" | awk '/install: / { print $4; exit }'` 
    digactual=`md5sum $file | awk '{print $1}'`
    #if ! test $digest = $digactual; then
    if [ "x$digest" != "x$digactual" ]; then
      die "  $pkg: $digactual did not match $digest, exiting"; fi





    file2=$(basename "$file" .bz2)
    echo -n "  $pkg: Uncompressing..."
    bunzip2 -c $file > /tmp/$file2
    rc=$?
    if [ $rc -gt 0 ]; then
      die "  $pkg:  bunzip2 -c $file failed with return code $rc, exiting.";  fi
    if [ "$command" == "fakeinstall" ]; then
      cat /tmp/$file2 | tar tf - > "/etc/setup/$pkg.lst"
    else    
      echo -n "Unpacking..."
      cat /tmp/$file2 | tar > "/etc/setup/$pkg.lst" xvf - -C /
    fi
    echo "done."
    rm -f /tmp/$file2
    gzip -f "/etc/setup/$pkg.lst"
    cd ../..
    
    # update the package database
    
    cat /etc/setup/installed.db | awk > /tmp/awk.$$ -v pkg="$pkg" -v bz=$file \
      '{if (ins != 1 && pkg < $1) {print pkg " " bz " 0"; ins=1}; print $0} \
       END{if (ins != 1) print pkg " " bz " 0"}'
    mv /etc/setup/installed.db /etc/setup/installed.db-save
    mv /tmp/awk.$$ /etc/setup/installed.db
    
    if [ "$command" == "fakeinstall" ]; then
      echo "  $pkg: Fake installed.";
    else
      pis=`ls /etc/postinstall/*.sh 2>/dev/null | wc -l`
      if test $pis -gt 0 && ! test $noscripts -eq 1;then
        echo -n "  $pkg: Running postinstall scripts..."
        for script in /etc/postinstall/*.sh; do
          echo -n "$script..."
          $script
          ret=$?
          mv $script $script.done
          if [ "x$ret" != "x0" ]; then
            echo -e "\n    Script $script exited with error code $ret. Hit any key to continue or ^C to exit."
            read -sn 1 scrap
          fi
        done
        echo
      fi    
    fi
    echo " "
  
}
function _splitfind() {
  name="$1"
  #extra="$2"
  #return
  for arg in $2 $3; do
#    echo "arg:$arg:arg";
    #if ( [ "x$arg" == "xsrc-only" ] || [ "x$arg" == "xobsolete" ]); then
    if [ ${#arg} -lt 9 ]; then
      extra="$arg"
    else
      desc="$arg"
    fi
  done
}

noscripts=0
noupdate=1
file=""
dofile=0
command=""
filepackages=""
packages=""

if [[ ${0##*/} =~ ^apt(-cyg)?[0-9]+(\.sh)?$ ]]; then
  b=${0##*/}
  b=${b##apt}
  b=${b##-cyg}
  b=${b%%.sh}
  if [[ $b =~ ^[0-9]+$ ]]; then
    let b--
    echo Forcing repo ${repos_url[$b]}
    set-setuprc "last-mirror" "${repos_url[$b]}"
  fi
fi

while test $# -gt 0; do
  case "$1" in

    --all|-a)
      DESCSEARCH=1
      shift
    ;;
    --repo|-r)
      die "Stub"
      shift
    ;;
    --mirror|-m)
      if ( ! [[ "$2" =~ ^(ftp|https?)://......*/.* ]]); then
        die "Invalid mirror: '$2'"
      fi
      set-setuprc "last-mirror" "$2"
      shift ; shift
    ;;

    --cache|-c)
      if [ ! -d "$2" ]; then
        die "Directory does not exist: $2"
      fi
      set-setuprc "last-cache" $(cygpath -aw "$2")
      shift ; shift
    ;;

    --noscripts)
      noscripts=1
      shift
    ;;
    --dry-run|--dry|-d)
      echo "Not installing anything"
      dryrun='[dry-run] '
      shift
    ;;
    --force|-o|--override|--obsolete)
      ALLOWOBSOLETE=1
      shift
    ;;
    --update|-u)
      noupdate=0
#1
      shift
    ;;

    --help)
      usage
      exit 0
    ;;

    --version)
      version
      exit 0
    ;;

    --file|-f)
      if ! test "-$2-" = "--"
      then
        file="$2"
        dofile=1
        shift
      else
        echo 1>&2 No file name provided, ignoring $1
      fi
      shift
    ;;

    update|fullshow|show|find|describe|packageof|install|dl|download|source|dlsrc|fakeinstall|depinstall|remove|fullfind|new)
      if test "-$command-" = "--"
      then
        command=$1
      else
        packages="$packages $1"
      fi
      shift

    ;;

    *)
      packages="$packages $1"
      shift

    ;;

  esac
done


if test $dofile = 1
then
  if test -f "$file"
  then
    filepackages="$filepackages `cat "$file" | awk '{printf "%s ", $0}'`"
  else
    echo File $file not found, skipping
  fi
  packages="$packages $filepackages"
fi


case "$command" in

  update)
    noupdate=0
    findworkspace
    getsetup

  ;;


  show)
    echo 1>&2 The following packages are installed:
    getinstalled
    for pkg in ${!INSTALLED*};do 
      eval declare ver=\$$pkg
      pkg=${pkg/INSTALLED_/}
      pkg=${pkg//DASHKLUDGE/-}
      pkg=${pkg//DOTKLUDGE/.}
      pkg=${pkg//PLUSKLUDGE/+}
      pkg="$pkg                                  "
      echo -ne "${pkg:0:30} $ver\n"
    done
  ;;
  
  fullshow)
    for i in $(echo /etc/setup/*.lst.gz|sed -r 's,(/etc/setup/|\.lst\.gz),,g');do zcat /etc/setup/$i.lst.gz|sed s,^,$i:,g;done
  ;;

  oldfind)

    checkpackages
    findworkspace
    getsetup
    getinstalled;
    for pkg in $packages; do
      echo ""
      echo Searching for installable packages matching $pkg:
      cmdfind $pkg
    done
  ;;

  find|fullfind)
    checkpackages
    getinstalled

  for (( mirrorc = 0 ; mirrorc < ${#repos_url[@]} ; mirrorc++ )); do
    
    mirror=${repos_url[$mirrorc]}
    mirrordir="`echo "$mirror" | sed -e "s/:/%3a/g" -e "s:/:%2f:g"`"
    mirrorname="${repos_name[$mirrorc]}"
    cache=$(get-setuprc "last-cache" '^[a-zA-Z]:\\...*')
    echo "Checking repo '$mirrorname', url: $mirror, dir: $cache"
    mkdir -p "$cache/$mirrordir"
    cd "$cache/$mirrordir"
    getsetup
    for pkg in $packages; do
      res="$res
"$(cmdfind $pkg $mirrorname $DESCSEARCH )
    done
    
  done
  if [ "x$COL" != "x" ]; then
    echo "$res"|sed -r 's/^/-_-/'|fold -sw $(($COL - 2))|sed -r 's/^/  /'|sed -r 's/^  \-_\-//'
  else
    echo "$res"
  fi
  ;;

  new)
    #checkpackages
    if [ "x$packages" == "x" ];then packages=".";fi
    getinstalled
    FIND="new"
  for (( mirrorc = 0 ; mirrorc < ${#repos_url[@]} ; mirrorc++ )); do
    
    mirror=${repos_url[$mirrorc]}
    mirrordir="`echo "$mirror" | sed -e "s/:/%3a/g" -e "s:/:%2f:g"`"
    mirrorname="${repos_name[$mirrorc]}"
    cache=$(get-setuprc "last-cache" '^[a-zA-Z]:\\...*')
    echo "Checking repo '$mirrorname', url: $mirror, dir: $cache"
    mkdir -p "$cache/$mirrordir"
    cd "$cache/$mirrordir"
    getsetup
    for pkg in $packages; do
      res="$res
"$(cmdfind $pkg $mirrorname $DESCSEARCH )
    done
    
  done
  if [ "x$COL" != "x" ]; then
    echo "$res"|sed -r 's/^/-_-/'|fold -sw $(($COL - 2))|sed -r 's/^/  /'|sed -r 's/^  \-_\-//'
  else
    echo "$res"
  fi
  ;;


  describe)

    checkpackages
    findworkspace
    getsetup
    for pkg in $packages
    do
      echo ""
      cat $SETUP.ini | awk -v query="$pkg" \
        'BEGIN{RS="\n\n@ "; FS="\n"; ORS="\n"} {if ($1 ~ query) {print $0 "\n"}}'
    done

  ;;


  packageof)

    checkpackages
    for pkg in $packages
    do
      key=`which "$pkg" 2>/dev/null | sed "s:^/::"`
      if test "-$key-" = "--"
      then
        key="$pkg"
      fi
      for manifest in /etc/setup/*.lst.gz
      do
        found=`cat $manifest | gzip -d | grep -c "$key"`
        if test $found -gt 0
        then
          package=`echo $manifest | sed -e "s:/etc/setup/::" -e "s/.lst.gz//"`
          echo Found $key in the package $package
        fi
      done
    done

  ;;

  source|dlsrc)
#set -x
    checkpackages
    findworkspace
    getsetup
#set -
    cd -
    for pkg in $packages; do
      dlpkg $pkg "src"
      echo "Mirror now $mirror"
    done
    exit

  ;;

  download|dl)
    checkpackages
    findworkspace
    getsetup
  cd -
  for pkg in $packages; do
      dlpkg $pkg
    done
    exit

  ;;

  install|depinstall|fakeinstall)
    checkpackages
    findworkspace
    getsetup
    INSTALLED=$(cat /etc/setup/installed.db|grep -v ^INSTALLED\.DB|cut -d ' ' -f1)
    packages=$(echo "$packages"|sed -r 's,(^ +| +$),,g')
    PACKAGES=$(echo "($packages)"|tr ' ' '|')
    echo "${dryrun}Checking dependencies for $packages..."
    for pkg in $packages; do
      getdeps $pkg
    done
    if [ "x$bad" != "x" ]; then
      echo "${dryrun}ABORTING. Could not resolve the following deps:"
      echo -e "\t$bad"
      exit 1
    fi
    diff=$(echo "$packages"|tr ' ' '\n'|egrep -v "^$PACKAGES\$"|tr '\n' ' '|sed -r 's,(^ +| +$),,g')
    if [ "x$diff" != "x" ]; then
      echo -e "${dryrun}The following dependencies are required:\n\t$diff"
      echo -ne "${dryrun}Do you want to continue? [Y/n] "
      read -sn 1 answer;
      if [ "x$answer" == 'xn' ]; then
        die "Aborting."
      fi
      echo
    fi
    #echo "==pkglist==$pkglist==mirrors==$pkgmlist==packages==$packages"
    declare -a inst=($pkglist)
    declare -a instm=($pkgmlist)

    for (( c = 0 ; c < ${#inst[@]} ; c++ )); do
      oldpwd="`pwd`"
      installpkg "${inst[$c]}" "${instm[$c]}"
      cd "$oldpwd"
    done
    exit
  ;;

  remove)

    checkpackages
    for pkg in $packages
    do

    already=`grep -c "^$pkg " /etc/setup/installed.db`
    if test $already = 0
    then
      echo Package $pkg is not installed, skipping
      continue
    fi

    dontremove="cygwin coreutils gawk bzip2 tar wget bash"
    for req in $dontremove
    do
      if test "-$pkg-" = "-$req-"
      then
        echo apt-cyg cannot remove package $pkg, exiting
        exit 1
      fi
    done

    if ! test -e "/etc/setup/$pkg.lst.gz"
    then
      echo Package manifest missing, cannot remove $pkg.  Exiting
      exit 1
    fi
    echo Removing $pkg

    # run preremove scripts

    if test -e "/etc/preremove/$pkg.sh"
    then
      "/etc/preremove/$pkg.sh"
      rm "/etc/preremove/$pkg.sh"
    fi

    cat "/etc/setup/$pkg.lst.gz" | gzip -d | awk '/[^\/]$/ {print "rm -f \"/" $0 "\""}' | sh
    rm "/etc/setup/$pkg.lst.gz"
    rm -f /etc/postinstall/$pkg.sh.done
    cat /etc/setup/installed.db | awk > /tmp/awk.$$ -v pkg="$pkg" '{if (pkg != $1) print $0}'
    mv /etc/setup/installed.db /etc/setup/installed.db-save
    mv /tmp/awk.$$ /etc/setup/installed.db
    echo Package $pkg removed

    done

  ;;

  *)

    usage

  ;;

esac

